iT邦幫忙

2018 iT 邦幫忙鐵人賽
2

大家看到總結別嚇到不是真的這系列文章的總結啦(汗
而是這幾天對於 JSON Web Token 的小總結,畢竟當時只教怎麼去實作卻沒深入的講解,且看大多網路上只有教學沒有深入探討原理,所以才打算另外寫一篇來說明為何要這樣做與一些名詞解釋。
所以今天不寫程式,我們來探討安全性,為了讓大家能都看得懂所以我都寫得很淺,若有錯誤地方也請多指教~

本文你將會學到

  • 了解 JWT 和 Bearer Token 的關係與 OAuth 2.0
  • 了解 HTTP Authentication 中有哪些 schemes
  • 客戶端向後端出示API Token的三種方式
  • Authenticate 的 API Error 錯誤訊息

JWT 和 Bearer Token 的關係

要存取某 API 時,若要身份驗證則在 JWT 前面加上字符串 Bearer 再放到 HTTP 請求的 Header 中,這個值就是 Bearer Token,至於為什麼要這樣做? HTTP 的認證「Authorization」方案有許多種格式,而 Bearer 就是其中一種且被定義在 Header 中的驗證方案,通常搭配於 JWT 上,Resource server 是資源服務器,即後端存放用戶生成的 API Token 的服務器。 Authorization server 的意思是認證服務器,即後端專門用來處理認證的服務器在我們系列實作是使用 JWT 機制,這些東西都是由 OAuth 2.0 中所定義出來的,在定義中說明了 Client 如何取得 Access Token 的方法,在這篇文章稍微提到就好若要完整解釋可能就是另一個領域了,在這系列文中就不多贅述,本篇只會說明基本使用方法跟注意事項。

Authentication schemes:

參考

客戶端向後端出示 API Token 的方式

客戶端(Client)向後端(Server)出示 API Token 的方式分為三種。

1. 放在 HTTP Header 裡面

此方法為 Resource Server 資源服務器,為本系列文中所實作的方式,使用 GET 請求方式並將 API Token 放在 Header 裡。

GET /api/article/personal HTTP/1.1
Host: localhost:3000
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjp7InVzZXJfaWQiOjEsInVzZXJfbmFtZSI6IkFuZHkxMCIsInVzZXJfbWFpbCI6ImFuZHlAZ21haWwuY29tIn0sImV4cCI6MTUxNTczODUxOSwiaWF0IjoxNTE1NzM3NjE5fQ.CLPeXhcxl2mdsL6-sUNFHFYABkTxmzx3YxEPyNih_FM

https://ithelp.ithome.com.tw/upload/images/20180114/20107247ankhTWE8bF.png

2. 放在 Request Body 裡面

此方法也有人用,選擇 POST 請求方式並把 API Token 放在 Body 裡傳送,本系列文中的 新增、修改內容都是使用此方式傳值。

POST /api/article/personal HTTP/1.1
Host: localhost:3000
Content-Type: application/x-www-form-urlencoded
token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjp7InVzZXJfaWQiOjEsInVzZXJfbmFtZSI6IkFuZHkxMCIsInVzZXJfbWFpbCI6ImFuZHlAZ21haWwuY29tIn0sImV4cCI6MTUxNTczODUxOSwiaWF0IjoxNTE1NzM3NjE5fQ.CLPeXhcxl2mdsL6-sUNFHFYABkTxmzx3YxEPyNih_FM

https://ithelp.ithome.com.tw/upload/images/20180114/20107247c35pHcinNq.png

3. 放在 URI 裡(Query Parameter)

通常不建議這種方式因為你的資訊會被暴露在前端使用者上,雖然是亂碼但還是會被有心時是利用的風險,但還是有被使用的時候,像中央氣象局的 API ,開發者必須先註冊後取得授權碼 API Token 後再將 API Token 放到網址上進行 Open Data 的存取,他這樣做也是有用意存在,畢竟它提供的每支 API 都是 GET 形式。

https://ithelp.ithome.com.tw/upload/images/20180114/20107247Mf5XSS7bCD.png

Authenticate 的 API Error 錯誤訊息

API Token 的驗證通常會遇到三個 HTTP Status Code 分別為 400 客戶端參數錯誤、401 登入失敗、403 權限不夠,這些都是 Resource Server 向 Client 端提示認證不過與拒絕存取的方式,幫各位整理以下表格:

Status Code 說明
400 (Bad Request) 遇到無法解讀 Request 的情況。
401 (Unauthorized) API Token 過期、無法解讀、或其他 Access Token 不合法的情況。
403 (Forbidden) 尚未提供 Bearer Token ,即資源服務器(Resource server) 找無資訊。

總結

Authorization 是用戶認證是後端最重要的一環,這邊最後整理幾項後端開發者必須去注意到的安全性問題,首先是盡量別把 API Token 外露在前端瀏覽器上以免被有心人士修改與攻擊例如儲存在 Cookie 中,且並全程使用 HTTPS 安全協定,最後將 API Token 設為有時效性的確保每次資料為最新狀態,當然還有更多安全的防護機制本系列文中沒詳細提到,像是偵測時間內 IP 位置多次請求 API Token 或是偵測到有不合法的存取行為......等,總之後端是整個專案中的心臟,所有想得到的問題都必須一一的去克服。

  • API Token 顯示給用戶
  • 全程使用 HTTPS 安全協定
  • 不要把 API Token 存在 Cookie
  • 定義有時效性的 API Token

文章同時發表於:https://andy6804tw.github.io/2018/01/14/get-personal-article(3)/

實作內容基本上就暫時到這邊,若各位還想繼續聽哪部分或是覺得哪裡不清楚需要再深入解釋的地方可以跟我說我可以再另外做番外篇哦 =)
接下來的內容就要進入最後的部署部分了(撒花


上一篇
[Day-34] (實作)使用JWT來存取API內容(下)
下一篇
[Day-36] 使用mocha來做單元測試
系列文
從無到有,打造一個漂亮乾淨俐落的 RESTful API43
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
taro
iT邦新手 5 級 ‧ 2019-05-14 12:01:35

想請問一下,因為api token不建議放在cookie傳遞,如果是網站登入後取得api token,而這token在每次請求都需向後端出示以証明會員身分,您會選擇放在哪裡呢?

10程式中 iT邦研究生 3 級 ‧ 2019-05-14 14:30:48 檢舉

可以考慮用localStorage
https://andy6804tw.github.io/2018/03/04/browser-localstorage/
此外安全起見可以設定token的有效期限

taro iT邦新手 5 級 ‧ 2019-05-15 10:16:22 檢舉

再請問一下,如果這token是放入用SSL傳輸並且限定httponly的cookie
,您還是覺得會有安全性的問題嗎?
因為Oauth 2.0比較建議的傳遞access token的方式有HTTP Header/Request Body...等。
我看來看去還是不是很了解比起用SSL傳輸並且限定httponly的cookie安全在哪裡,可以參考您的看法嗎?

10程式中 iT邦研究生 3 級 ‧ 2019-05-17 17:29:52 檢舉

只能說這種機密的token盡量避免讓情端使用者輕易的拿到,若真的被有心人士拿到的話後端是最後一道防線。在我教學中使用第三方JWT這個套件可以設定金鑰(key)他可以幫你的token做加解密動作。
我建議有關帳戶或資料庫重要資料的存取勢必要在HTTPS下做傳輸比較安全。

我要留言

立即登入留言